package com.delivery.deliverysystem.service.impl;

import com.delivery.deliverysystem.exception.RException;
import com.delivery.deliverysystem.service.CommonService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

@Service
@Slf4j
public class CommonServiceImpl implements CommonService {

    @Value("${upload.path}")
    private String uploadPath;

    //限制上传文件的类型
    private static final List<String> ALLOWED_IMAGE_TYPES = Arrays.asList(
            "image/jpeg", "image/png", "image/gif", "image/bmp"
    );

    @Override
    @Transactional(rollbackFor = Exception.class)
    public String uploadFile(MultipartFile file,String uploadFolder) throws RException {
        if(file.isEmpty()) throw new RException("请选择要上传的图片",500);
        String contentType = file.getContentType();
        if(contentType==null || !ALLOWED_IMAGE_TYPES.contains(contentType)){
            throw new RException("仅支持上传 JPEG、PNG、GIF、BMP 格式的图片",500) ;
        }
        try {
            //合并基础路径和上传的指定文件夹
            String fullPath = uploadPath + File.separator + uploadFolder;
            // 获取相对路径对应的文件对象
            File uploadDir = new File(fullPath);
            if (!uploadDir.exists()) {
                if(!uploadDir.mkdirs()) throw new RException("创建文件夹失败",500);
            }
            // 生成唯一文件名
            String fileName = UUID.randomUUID() + "_" + file.getOriginalFilename();
            File dest = new File(uploadDir, fileName);
            file.transferTo(dest);

            // 相对路径
            String relativePath ="/uploads" + "/" + uploadFolder + "/" + fileName;
            log.info("图片上传成功，路径: {}", relativePath);
            return relativePath;
        } catch (IOException e) {
            log.error("图片上传失败", e);
            throw new RException("图片上传失败",500);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteFile(String filePath) throws RException, IOException {
        // 1. 规范化路径处理
        String cleanedRelativePath = filePath.replaceFirst("^/uploads", "");

        // 2. 统一使用正斜杠并去除可能的前导斜杠
        cleanedRelativePath = cleanedRelativePath.replace("\\", "/").replaceAll("^/+", "");

        // 3. 构建完整路径
        File baseDir = new File(uploadPath).getCanonicalFile();
        File fileToDelete = new File(baseDir, cleanedRelativePath).getCanonicalFile();

        // 4. 安全检查：确保目标文件在基础目录内
        if (!fileToDelete.getCanonicalPath().startsWith(baseDir.getCanonicalPath())) {
            throw new RException("非法文件路径", 403);
        }
        //检查文件是否存在
        if (fileToDelete.exists() && fileToDelete.isFile()) {
            try {
                if (fileToDelete.delete()) {
                    log.info("图片删除成功，路径: {}", fileToDelete.getPath());
                    return true;
                } else {
                    log.error("图片删除失败，路径: {}", fileToDelete.getPath());
                    throw new RException("图片删除失败", 500);
                }
            } catch (SecurityException e) {
                log.error("删除文件时发生安全异常，路径: {}", fileToDelete.getPath(), e);
                throw new RException("删除文件时发生安全异常", 500, e);
            }
        } else {
            log.warn("文件不存在，路径: {}", fileToDelete.getPath());
            throw new RException("文件不存在", 404);
        }
    }
}
